﻿using GeneticAlgorithm.Interfaces;
using GeneticAlgorithm.Models;
using Prism.Commands;
using Prism.Mvvm;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace GeneticAlgorithm.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string title = "Prism Application";
        public string Title
        {
            get { return title; }
            set { SetProperty(ref title, value); }
        }

        private string iterationNumber;
        public string IterationNumber
        {
            get { return iterationNumber; }
            set { SetProperty(ref iterationNumber, value); }
        }

        private string initialPopulationNumber;
        public string InitialPopulationNumber
        {
            get { return initialPopulationNumber; }
            set { SetProperty(ref initialPopulationNumber, value); }
        }

        public DelegateCommand<object> GenerateCommand { get; set; }

        public MainWindowViewModel()
        {
            GenerateCommand = new DelegateCommand<object>(ExecGenerate);
        }

        private async void ExecGenerate(object OutField)
        {
            RichTextBox richTextBox = OutField as RichTextBox;
            //var imageGenerateGeneticAlgorithms = new List<ImageGenerateGeneticAlgorithm>(100);
            //for (int i = 0; i < 100; i++)
            //{
            //    imageGenerateGeneticAlgorithms.Add(new ImageGenerateGeneticAlgorithm()
            //    {
            //        Condition = StopCondition.ReachIterationNumber,
            //        IterationNumber = int.Parse(IterationNumber),
            //        InitialPopulationNumber = int.Parse(InitialPopulationNumber),
            //    });
            //}
            //var resultPopulation = new List<IEvolvable<int>>(100);
            //await CalculateAsync(imageGenerateGeneticAlgorithms, resultPopulation);
            //StringBuilder stringBuilder = new StringBuilder();
            //foreach (var item in resultPopulation)
            //{
            //    stringBuilder.AppendLine((item as Matrix).GeneSequenceToString() + " " + item.Fitness);
            //}
            //richTextBox.AppendText(stringBuilder.ToString());
            ImageGenerateGeneticAlgorithm imageGenerateGeneticAlgorithm = new ImageGenerateGeneticAlgorithm()
            {
                Condition = StopCondition.ReachIterationNumber,
                IterationNumber = int.Parse(IterationNumber),
                InitialPopulationNumber = int.Parse(InitialPopulationNumber),
            };
            imageGenerateGeneticAlgorithm.Execute();
            richTextBox.AppendText((imageGenerateGeneticAlgorithm.BestIndividual as Matrix).GeneSequenceToString());
        }

        private Task CalculateAsync(List<ImageGenerateGeneticAlgorithm> geneticAlgorithms, List<IEvolvable<int>> resultPopulation)
        {
            var result = new TaskCompletionSource();
            List<Thread> threads = new List<Thread>(100);
            for (int i = 0; i < 99; i++)
            {
                threads.Add(new Thread(() =>
                {
                    geneticAlgorithms[i].Execute(geneticAlgorithms[i].GenerateInitialPopulation());
                    resultPopulation.Add(geneticAlgorithms[i].BestIndividual);
                    bool b = true;
                    foreach (var item in threads)
                        b &= item.ThreadState == ThreadState.Stopped;
                    if (b)
                        result.SetResult();
                })
                { IsBackground = true });
            }
            foreach (var item in threads)
                item.Start();
            return result.Task;
        }

    }
}
